#include "sqldatabase.h"

#include "common.h"

// 初始化静态成员
SqlDatabase* SqlDatabase::m_instance = nullptr;
QMutex SqlDatabase::m_mutex;

SqlDatabase::SqlDatabase(const QString& server, const QString& database, const QString& user, const QString& password)
    : m_server(server), m_database(database), m_user(user), m_password(password), m_connected(false) {


    // 确保加载 SQLite 驱动
    if (!QSqlDatabase::isDriverAvailable("QSQLITE")) {
        qCritical() << "SQLite driver not available!";
        return;
    }

    // 设置数据库连接信息
    if (QSqlDatabase::contains("qt_sql_default_connection")) {
         m_db = QSqlDatabase::database("qt_sql_default_connection");  // 默认数据库
    } else {
        m_db = QSqlDatabase::addDatabase(DATABASE_TYPE);  // 数据库类型
    }

}

SqlDatabase::~SqlDatabase() {
    //数据库关闭
    close();
}

SqlDatabase* SqlDatabase::instance(const QString& server, const QString& database, const QString& user, const QString& password) {

    // 双重检查锁
    if (m_instance == nullptr) {
        // 如果实例不存在，创建实例
        QMutexLocker locker(&m_mutex); // 加锁，保证线程安全
        if(m_instance == nullptr){
            m_instance = new SqlDatabase(server, database, user, password);
        }
    }
    return m_instance;
}

void SqlDatabase::release() {
    QMutexLocker locker(&m_mutex);

    if (m_instance) {
        delete m_instance;
        m_instance = nullptr;
    }
}

bool SqlDatabase::open() {
    if (m_connected) {
        qDebug() << "Already connected to the database!";
        return true;
    }

    // 设置数据库连接信息
    if (QString(DATABASE_TYPE) == "QSQLITE") {
        // 对于 SQLite 只需要设置数据库名称即可
        m_db.setDatabaseName(m_database);
    } else {
        m_db.setHostName(m_server);           // 服务器名称
        m_db.setDatabaseName(m_database);     // 数据源名称(数据库)
        m_db.setUserName(m_user);             // 用户名
        m_db.setPassword(m_password);         // 密码
    }
    // 打开数据库
    if (m_db.open()) {
        m_connected = true;
        qDebug() << "Successfully connected to the database.";
        return true;    // 连接成功
    } else {
        qDebug() << "Error: Unable to connect to database!";
        qDebug() << m_db.lastError().text();
        return reconnect();  // 连接失败, 尝试重新连接
    }
}

void SqlDatabase::close() {
    if (m_db.isOpen()) {
        m_db.close();
        m_connected = false;
        qDebug() << "Database connection closed.";
    }
}

bool SqlDatabase::isOpen() const {
    return m_connected;
}

QSqlQuery SqlDatabase::executeQuery(const QString& queryStr) {
    QSqlQuery query;

    if (!query.exec(queryStr)) {
        qDebug() << "Error executing query:" << queryStr;
        qDebug() << "Error:" << query.lastError().text();
    }
    return query;
}

QSqlDatabase SqlDatabase::database() const {
    return m_db;
}

QString SqlDatabase::buildConnectionString() const {
    QString connStr = QString("Driver={Om_dbC Driver 17 for SQL Server};Server=%1;Database=%2;")
                      .arg(m_server)
                      .arg(m_database);

    if (!m_user.isEmpty() && !m_password.isEmpty()) {
        connStr.append(QString(";Uid=%1;Pwd=%2").arg(m_user).arg(m_password));
    }

    return connStr;
}

bool SqlDatabase::reconnect() {
    qDebug() << "Attempting to reconnect to the database...";

    // 尝试重新连接几次（例如：3次）
    for (int i = 0; i < 3; ++i)
    {
        if (m_db.open()) {
            m_connected = true;
            qDebug() << "Successfully connected to the database.";
            return true;
        } else {
        qDebug() << "Error: Unable to connect to database!";
        qDebug() << m_db.lastError().text();
    }
        qDebug() << "Reconnect attempt" << (i + 1) << "failed!";
    }

    qDebug() << "All reconnect attempts failed.";
    return false;
}
